import * as THREE from 'three'
import { Utils } from './utils.js'
// room1_1 room_out_1_1 room_out_1_2 room1_2
// room2_1 room_out_2_1 room_out_2_2 room2_2
// room2_1 room_out_2_1 free2_1 free2_5 room_out_2_5 room2_5
// room1_1 room_out_1_1 stairs_right3 stairs_right2 stairs_right1 free2_3 room_out_2_1 room_2_1
// room1_1 room_out_1_1 stairs_left3 stairs_left2 stairs_left1 free2_6 room_out_2_5 room_2_5
const room2isNearBy = (start:string, end:string) => {
    const reg1 = /^(1|2|3|4)$/
    const reg2 = /^(5|6|7|8)$/
    if ((start.match(reg1) && end.match(reg1)) || (start.match(reg2) && end.match(reg2))) {
        return true
    }
    return false
}
// 获取当前坐标距离最近的起始位置名称
const getNearName = (vec3:THREE.Vector3, vecName:string) => {
    if (!vec3) {
        vec3 = Utils.getFreePoint()
    }
    
    let name = '',distance = 10000
    for(const n in playerPosition) {
        if (n.match(/room\d_\d/)) {
            const item = playerPosition[n]
            if (item.y === vec3.y) {
                
                const _distance = item.distanceTo(vec3)
                if (_distance < distance)  {
                    distance = _distance
                    name = n
                }
            } else if (vecName === 'stairs_right1') {
                name = 'room2_1'
            } else if (vecName === 'stairs_right2') {
                name = 'room1_1'
            } else if (vecName === 'stairs_left1') {
                name = 'room2_5'
            } else if (vecName === 'stairs_left2') {
                name = 'room1_5'
            }
        }
        
        // ...实现它！！！
    }
    return {
        name,
        vec3
    }
}

const getNearByName = (startName:string, endName:string | THREE.Vector3) => {
    const start = getNearName(playerPosition[startName], startName)
    const end = typeof endName === 'string' ? getNearName(playerPosition[endName], endName) : getNearName(endName, '')
    return {
        startName: start.name,
        startVec3: start.vec3,
        endName: end.name,
        endVec3: end.vec3
    }
}
// 路线轨迹
const getRouteTrack = (startName:string, endName:string | THREE.Vector3) => {
    const regRoom1 = /room1_(\d)/
    const regRoom2 = /room2_(\d)/
    let isReverse = false
    if (typeof endName === 'string' && startName.match(/room2/) && endName.match(/room1/)) {
        let tmp = endName
        endName = startName
        startName = tmp
        isReverse = true
    }
    let a:any,b:any,result:any[] = []
    
    if (typeof endName === 'string' && (a = startName.match(regRoom1)) && (b = endName.match(regRoom1))) {
        result = `room1_${a[1]} room_out_1_${a[1]} room_out_1_${b[1]} room1_${b[1]}`.split(' ')
    } else if (typeof endName === 'string' && (a = startName.match(regRoom2)) && (b = endName.match(regRoom2))) {
        if (room2isNearBy(a[1], b[1])) {
            result = `room2_${a[1]} room_out_2_${a[1]} room_out_2_${b[1]} room2_${b[1]}`.split(' ')
        } else {
            const free = a[1] < b[1] ? `free2_1 free2_4 free2_5` : `free2_5 free2_4 free2_1`
            result = `room2_${a[1]} room_out_2_${a[1]} ${free} room_out_2_${b[1]} room2_${b[1]}`.split(' ')
        }
    } else if (typeof endName === 'string' && (a = startName.match(regRoom1)) && (b = endName.match(regRoom2))) {
        if (room2isNearBy(a[1], b[1])) {
            const free = (a[1] <= 4 && b[1] <= 4) ? `stairs_right3 stairs_right2 stairs_right1 free2_3` : `stairs_left3 stairs_left2 stairs_left1 free2_6`
            result = `room1_${a[1]} room_out_1_${a[1]} ${free} room_out_2_${b[1]} room2_${b[1]}`.split(' ')
        } else {
            const free = a[1] > 4 ? `stairs_right3 stairs_right2 stairs_right1 free2_3` : `stairs_left3 stairs_left2 stairs_left1 free2_6`
            result = `room1_${a[1]} room_out_1_${a[1]} ${free} room_out_2_${b[1]} room2_${b[1]}`.split(' ')
        }
    } else {
        
        const data = getNearByName(startName, endName)
        
        result = getRouteTrack(data.startName, data.endName)
        
        if (startName === 'free') {
            result.splice(0, 1, data.startVec3)
        } else {
            result = result.slice(result.indexOf(startName))
        }
        if (endName === 'free' || typeof endName === 'object') {
            result.pop()
            result.pop()
            result.push(data.endVec3)
        } else {
            result = result.slice(0, result.indexOf(endName) + 1)
        }
        
        
    }
    if (isReverse) {
        result = result.reverse()
    }
    return result
}

const playerPosition:{
    [key:string]: THREE.Vector3
} = {
    // 一楼
    room1_1: new THREE.Vector3(13, 0, -18.5),
    room1_2: new THREE.Vector3(5.5, 0, -18.5),
    room1_3: new THREE.Vector3(-2, 0, -18.5),
    room1_4: new THREE.Vector3(-12, 0, -18.5),
    room1_5: new THREE.Vector3(13, 0, 18.5),
    room1_6: new THREE.Vector3(5, 0, 18.5),
    room1_7: new THREE.Vector3(-2.5, 0, 18.5),
    room1_8: new THREE.Vector3(-10.5, 0, 18.5),
    // 一楼运动坐标点-门口
    room_out_1_1: new THREE.Vector3(12, 0, -10),
    room_out_1_2: new THREE.Vector3(4.5, 0, -11.5),
    room_out_1_3: new THREE.Vector3(-2, 0, -11.5),
    room_out_1_4: new THREE.Vector3(-11, 0, 11),
    room_out_1_5: new THREE.Vector3(12, 0, 11),
    room_out_1_6: new THREE.Vector3(4, 0, 11),
    room_out_1_7: new THREE.Vector3(-2, 0, 11),
    room_out_1_8: new THREE.Vector3(-10.5, 0, 18.5),
    // 二楼
    room2_8: new THREE.Vector3(13, 7.7, 18.5),
    room2_7: new THREE.Vector3(5.5, 7.7, 18.5),
    room2_6: new THREE.Vector3(-2.5, 7.7, 18.5),
    room2_5: new THREE.Vector3(-10.5, 7.7, 18.5),
    room2_4: new THREE.Vector3(-11, 7.7, -16.5),
    room2_3: new THREE.Vector3(-2.5, 7.7, -16.5),
    room2_2: new THREE.Vector3(5.5, 7.7, -16.5),
    room2_1: new THREE.Vector3(11.5, 7.7, -16.5),
    // 二楼运动坐标点-门口
    room_out_2_8: new THREE.Vector3(11, 7.7, 11),
    room_out_2_7: new THREE.Vector3(5, 7.7, 11.5),
    room_out_2_6: new THREE.Vector3(-3, 7.7, 11),
    room_out_2_5: new THREE.Vector3(-11.5, 7.7, 11),
    room_out_2_4: new THREE.Vector3(-11, 7.7, -11),
    room_out_2_3: new THREE.Vector3(-2.5, 7.7, -11),
    room_out_2_2: new THREE.Vector3(5, 7.7, -11),
    room_out_2_1: new THREE.Vector3(12, 7.7, -11),

    
    // 楼梯上下楼
    stairs_left1: new THREE.Vector3(23.5, 4, 9.5),
    stairs_left2: new THREE.Vector3(23, 4, 5.5),
    stairs_left3: new THREE.Vector3(15, 0, 5.5),

    stairs_right1: new THREE.Vector3(23.5, 4, -11),
    stairs_right2: new THREE.Vector3(23.5, 4, -6),
    stairs_right3: new THREE.Vector3(15, 0, -6),

    // 二楼运动坐标点-路口
    free2_1: new THREE.Vector3(0, 8, -11), // 路口中间
    free2_2: new THREE.Vector3(-24.5, 8, -11), // 墙角
    free2_3: new THREE.Vector3(16, 8, -11), //下楼梯口
    free2_4: new THREE.Vector3(-0.5, 8, 0.5), // 通道中间
    free2_5: new THREE.Vector3(-0.5, 8, 10),	
    free2_6: new THREE.Vector3(15.5, 8, 10),	// 下楼梯口
    free2_7: new THREE.Vector3(-25, 8, 10),// 墙角
}
export const Plan = {
    getAllRooms() {
        return [
            'room1_1', 'room1_2', 'room1_3', 'room1_4', 'room1_5', 'room1_6', 'room1_7', 'room1_8',
            'room2_1', 'room2_2', 'room2_3', 'room2_4', 'room2_5', 'room2_6', 'room2_7', 'room2_8'
        ]
    },
    to(name: string, player:THREE.Group | THREE.Object3D) {
        if (name === 'free') {
            player.position.copy(Utils.getFreePoint())
        } else {
            player.position.copy(playerPosition[name])
        }
        
        player.userData.postionName = name
    },
    toRoom(toPosName:string | THREE.Vector3, player:THREE.Group | THREE.Object3D):THREE.Vector3[] {
        const playerPositionName = player.userData.postionName
        
        let _toPosName = toPosName
        if (_toPosName === 'free2_2') {
            _toPosName = 'room2_1'
        }
        if (_toPosName === 'free2_7') {
            _toPosName = 'room2_5'
        }
        const arr = getRouteTrack(playerPositionName, _toPosName)
        if (toPosName === 'free2_7') {
            arr.splice(arr.length - 1, 1, 'free2_7')
        }
        return arr.map(v => typeof v === 'string' ? playerPosition[v] : v)
    }
}